using System;
using System.ComponentModel;
using System.Windows.Media.Imaging;
using Graphe.Data;
using Graphe;
using System.Windows.Media;
using Microsoft.Win32;
using System.Security;

namespace Graphe
{
    public class DocumentImage : INotifyPropertyChanged
    {
        #region Constructor

        public DocumentImage(string path)
        {
            Path = path;
            SourceUri = new Uri(path);
            Frame = BitmapFrame.Create(SourceUri);
            _thumbnail = Frame.Thumbnail;
            Self = this;
        }

        #endregion
        #region Constants

        // TODO: Determine default size used by OS
        private const int _DEFAULT_THUMBNAIL_SIZE = 100;

        #endregion
        #region Private Instance Fields

        private string _path;
        private BitmapFrame _frame;
		private BitmapSource _thumbnail;
        private Uri _sourceUri;
        private string _fileName;
        private string _startReference;
        private string _endReference;
        private string _manuscriptName;
        private int _imageNumber;

        #endregion
        #region Public Properties

        public string Path
        {
            get { return _path; }
            set
            {
                _path = value;

                _fileName = _path.Substring(_path.LastIndexOf("\\") + 1, _path.Length - _path.LastIndexOf("\\") - 1);
            }
        }

        public BitmapFrame Frame
        {
            get { return _frame; }
            set { _frame = value; }
        }

		public BitmapSource Thumbnail
		{
			get
			{
				if(null == _thumbnail)
				{
					_thumbnail = Frame.Thumbnail;
                    //if (null == _thumbnail)
                    //    _thumbnail = CreateThumbnail(Frame);
				}
				return _thumbnail;
			}
		}

		private static int GetThumbnailSize()
		{
			try
			{
				RegistryKey key = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Explorer");
				if(null != key)
				{
					object value = key.GetValue("ThumbnailSize");
					if(null != value)
						return (int)value;
				}
			}
			catch(SecurityException)
			{
				// Intentionally left blank; use default size if user doesn't have permission to read the registry
			}
			return _DEFAULT_THUMBNAIL_SIZE;
		}

        public Uri SourceUri
        {
            get { return _sourceUri; }
            set { _sourceUri = value; }
        }

        public string FileName
        {
            get
            {
                return _fileName;
            }
        }

        public string StartReference
        {
            get { return _startReference; }
            set
            {
                _startReference = value;

                NotifyPropertyChanged("StartReference");

                HasReferences = true;
            }
        }

        public string EndReference
        {
            get { return _endReference; }
            set
            {
                _endReference = value;

                NotifyPropertyChanged("EndReference");

                HasReferences = true;
            }
        }

        public bool HasReferences
        {
            get
            {
                if (!String.IsNullOrEmpty(StartReference) || !String.IsNullOrEmpty(StartReference))
                    return true;

                return false;
            }
            set
            {
                //This value doesn't really need to be stored, since it is calc'd. However, since
                //  the UI depends on this value, we still need to raise NotifyPropertyChanged when
                //  it needs to be updated.
                NotifyPropertyChanged("HasReferences");
            }
        }

        public bool HasThumbnail
        {
            get
            {
                if (_thumbnail == null)
                    return false;
                else
                    return true;
            }
            set
            {
                NotifyPropertyChanged("HasThumbnail");
            }
        }

        //TODO: This is a total hack for another WPF hack. Delete!
        public DocumentImage Self { get; set; }

        public string ManuscriptName
        {
            get { return _manuscriptName; }
            set { _manuscriptName = value; }
        }

        public int ImageNumber
        {
            get { return _imageNumber; }
            set { _imageNumber = value; }
        }

        #endregion

        public static DocumentImageCollection GetImages(string directory)
        {
            return ManuscriptImageProvider.Instance.GetImages(directory);
        }

        public void Reload()
        {
            Frame = BitmapFrame.Create(SourceUri);
        }

        private static BitmapSource CreateThumbnail(BitmapFrame frame)
        {
            // TODO: get from registry
            int thumbnailSize = GetThumbnailSize();

            double scaleFactor;
            if (Math.Abs(frame.Width - thumbnailSize) > Math.Abs(frame.Height - thumbnailSize))
            {
                scaleFactor = thumbnailSize / frame.Width;
            }
            else
            {
                scaleFactor = thumbnailSize / frame.Height;
            }
            TransformedBitmap thumbnail = new TransformedBitmap(frame, new ScaleTransform(scaleFactor, scaleFactor));
            return thumbnail;
        }

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

        #endregion
    }
}
